package cave.ui;

import java.util.ArrayList;
import android.graphics.Color;
import android.util.FloatMath;
import cave.game.InputEvent;
import cave.renderer.RenderList;
import cave.renderer.Texture;

public class CheckBox implements DynamicUiItem {
	
	private float x, y;
	private float width, height;
	private float red, green, blue, alpha;
	private float[] orientation;
	private CheckBoxListener listener;
	private boolean checked, enabled, pressed;
	private int pointerId;
	private Texture texChecked, texNotChecked, texPressed, texDisabled;

	public CheckBox(float x, float y, float width, float height, Texture texChecked, Texture texNotChecked,
			Texture texPressed, Texture texDisabled, boolean isChecked, CheckBoxListener listener) {
		this(x, y, width, height, texChecked, texNotChecked, texPressed, texDisabled,
				isChecked, listener, 1.0f, 1.0f, 1.0f, 1.0f);
	}
	
	public CheckBox(float x, float y, float width, float height, Texture texChecked, Texture texNotChecked,
			Texture texPressed, Texture texDisabled, boolean isChecked, CheckBoxListener listener, int color) {
		this(x, y, width, height, texChecked, texNotChecked, texPressed, texDisabled,
				isChecked, listener, Color.red(color) / 255.0f, Color.green(color) / 255.0f,
				Color.blue(color) / 255.0f, Color.alpha(color) / 255.0f);
	}
	
	public CheckBox(float x, float y, float width, float height, Texture texChecked, Texture texNotChecked,
			Texture texPressed, Texture texDisabled, boolean isChecked, CheckBoxListener listener,
			float red, float green, float blue, float alpha) {
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
		this.texChecked = texChecked;
		this.texNotChecked = texNotChecked;
		this.texPressed = texPressed;
		this.texDisabled = texDisabled;
		this.checked = isChecked;
		this.listener = listener;
		this.red = red;
		this.green = green;
		this.blue = blue;
		this.alpha = alpha;
		orientation = new float[2];
		orientation[0] = 0.0f;
		orientation[1] = 1.0f;
		enabled = true;
		pointerId = -1;
		texChecked.incUsers();
		texNotChecked.incUsers();
		texPressed.incUsers();
		texDisabled.incUsers();
	}
	
	@Override
	public void update(float dt, ArrayList<InputEvent> events) {
		if (enabled) {
			InputEvent event;
			for (int i = 0; i < events.size(); i++) {
				event = events.get(i);
				if (!event.isInUse()) {
					switch (event.getType()) {
					case UP:
						if (pressed && pointerId == event.getPointerId() &&
								event.getX() > x && event.getX() < x + width &&
								event.getY() > y && event.getY() < y + height) {
							checked = !checked;
							listener.stateChanged(checked);
							pointerId = -1;
							pressed = false;
						}
						break;
						
					case DOWN:
						if (!pressed &&
								event.getX() > x && event.getX() < x + width &&
								event.getY() > y && event.getY() < y + height) {
							pointerId = event.getPointerId();
							pressed = true;
						}
						break;
						
					case MOVE:
						if (pressed && pointerId == event.getPointerId() && !(
								event.getX() > x && event.getX() < x + width &&
								event.getY() > y && event.getY() < y + height)) {
							pressed = false;
							pointerId = -1;
						}
						break;
					}
				}
			}
		}
		
	}

	@Override
	public void draw(RenderList renderList) {
		if (!enabled) {
			renderList.addScreenData(x, y, width, height, orientation[0], orientation[1],
					texDisabled, red, green, blue, alpha);
		} else if (pressed) {
			renderList.addScreenData(x, y, width, height, orientation[0], orientation[1],
					texPressed, red, green, blue, alpha);
		} else if (checked) {
			renderList.addScreenData(x, y, width, height, orientation[0], orientation[1],
					texChecked, red, green, blue, alpha);
		} else {
			renderList.addScreenData(x, y, width, height, orientation[0], orientation[1],
					texNotChecked, red, green, blue, alpha);
		}
	}

	@Override
	public void destroy() {
		texChecked.decUsers();
		texNotChecked.decUsers();
		texPressed.decUsers();
		texDisabled.decUsers();
	}
	
	public void setChecked(boolean checked) {
		if (this.checked != checked) {
			this.checked = checked;
			listener.stateChanged(checked);
		}
	}
	
	public boolean getState() {
		return checked;
	}
	
	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}
	
	public void setOrientation(float x, float y) {
		orientation[0] = x; orientation[1] = y;
	}
	
	public void setOrientation(float radians) {
		orientation[0] = FloatMath.cos(radians + (float)Math.PI/2);
		orientation[1] = FloatMath.sin(radians + (float)Math.PI/2);
	}
	
	public float[] getOrientation() {
		return orientation;
	}
	
	public void setPosition(float x, float y) {
		this.x = x;
		this.y = y;
	}
	
	public float getX() {
		return x;
	}
	
	public float getY() {
		return y;
	}
	
	public void setX(float x) {
		this.x = x;
	}
	
	public void setY(float y) {
		this.y = y;
	}
	
	public float getWidth() {
		return width;
	}
	
	public float getHeight() {
		return height;
	}
	
	public void setWidth(float width) {
		this.width = width;
	}
	
	public void setHeight(float height) {
		this.height = height;
	}
		
}
